#ifndef __OPENCL_RUNTIME_H
#define __OPENCL_RUNTIME_H

#include "opencl_wrapper.h"
#include <CL/cl2.hpp>
#include "common/common.h"
#include "common/define.h"
#include "common/log.h"

#define SHARING_MEM_WITH_OPENGL

namespace PanNN
{
    namespace OpenCL
    {
        class OpenCLRuntime
        {
        public:
            OpenCLRuntime();
            virtual ~OpenCLRuntime();

            ErrorCode Init();

            struct GpuInfo
            {
                enum GpuType
                {
                    OTHER = 0,
                    ADRENO = 1,
                    MALI = 2,
                    MALI_T = 3,
                    MALI_G = 4
                };
                GpuType m_type = OTHER;
            };

            GpuInfo ParseGpuInfo(std::string deviceName, std::string deviceVersion);
            ErrorCode InitGPUDevice(std::vector<cl::Platform> *platforms);
            ErrorCode InitQueue(std::vector<cl::Platform> *platforms);

            static std::string CLErrorCode(cl_int errorCode);

            enum InitState
            {
                UnInit = 0,
                InitSuccess = 1,
                InitFailed = 2
            };
            static InitState m_initState;

            void *m_handle = nullptr;

            cl::Platform m_platforms;
            cl::Device *m_device = nullptr;
            cl::Context *m_context = nullptr;
            cl::CommandQueue *m_defaultCmdQueue = nullptr;
            cl::CommandQueue *m_profilingCmdQueue = nullptr;
            GpuInfo m_gpuInfo;

            std::vector<size_t> m_maxWorkItemSizes;
            uint64_t m_maxWorkGroupSize = 1;
            cl_uint m_imagePitchAlign = 0;
            uint64_t m_globalMemeryCachesize = 0;
            uint32_t m_computeUnits = 0;
            uint32_t m_maxFreq = 0;
            cl_device_svm_capabilities m_svmCapabilities = 0;
            bool m_supportFP16 = false;
            uint64_t m_globalMemerySize = 0;
            uint64_t m_maxAllocSize = 0;
            uint64_t m_maxImage2dWidth = 0;
            uint64_t m_maxImage2dHeight = 0;
            std::string m_supportedExtensions = "";
            uint m_cacheLineSize = 1;
        };
    } // namespace OpenCL
} // namespace PanNN
#endif // __OPENCL_RUNTIME_H
